﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace ProceduralGolf
{

    class TextureThresholder : TextureEffect
    {
        private GraphicsDevice graphics;
        private Effect thresholdEffect;

        public TextureThresholder(Game game)
        {
            graphics = game.GraphicsDevice;
            thresholdEffect = game.Content.Load<Effect>("threshold");
            spriteBatch = new SpriteBatch(graphics);
        }

        public Texture2D threshold(Texture2D tex)
        {
            return threshold(tex, 0.5f, Color.Black, Color.White);
        }

        public Texture2D threshold(Texture2D tex, float threshold)
        {
            return this.threshold(tex, threshold, Color.Black, Color.White);
        }

        public Texture2D threshold(Texture2D tex, float threshold, Color color1, Color color2)
        {
            GraphicsMutex.GetMutex().WaitOne();

            Texture2D result;
            RenderTarget2D target = new RenderTarget2D(graphics, tex.Width, tex.Height, 1, graphics.PresentationParameters.BackBufferFormat);
            DepthStencilBuffer stencilBuffer = new DepthStencilBuffer(graphics, tex.Width, tex.Height, graphics.DepthStencilBuffer.Format);
            DepthStencilBuffer oldBuffer = graphics.DepthStencilBuffer;

            graphics.DepthStencilBuffer = stencilBuffer;
            graphics.SetRenderTarget(0, target);
            graphics.Clear(Color.Black);

            thresholdEffect.Begin();
            thresholdEffect.Parameters["threshold"].SetValue(threshold);
            thresholdEffect.Parameters["color1"].SetValue(color1.ToVector4());
            thresholdEffect.Parameters["color2"].SetValue(color2.ToVector4());

            foreach (EffectPass pass in thresholdEffect.CurrentTechnique.Passes)
            {
                spriteBatch.Begin(SpriteBlendMode.None, SpriteSortMode.Immediate, SaveStateMode.None);
                pass.Begin();

                spriteBatch.Draw(tex, new Rectangle(0, 0, tex.Width, tex.Height), Color.White);
                pass.End();
                spriteBatch.End();
            }

            thresholdEffect.End();

            graphics.SetRenderTarget(0, null);
            graphics.DepthStencilBuffer = oldBuffer;

            result = target.GetTexture();

            stencilBuffer.Dispose();
            target.Dispose();

            GraphicsMutex.GetMutex().ReleaseMutex();

            return result;

        }


        //public Texture2D threshold(Texture2D tex, float threshold, Color color1, Color color2)
        //{
        //    Texture2D result;
        //    RenderTarget2D target = new RenderTarget2D(graphics, tex.Width, tex.Height, 1, graphics.PresentationParameters.BackBufferFormat);
            
        //    graphics.SetRenderTarget(0, target);
            
        //    thresholdEffect.Begin();
        //    thresholdEffect.Parameters["threshold"].SetValue(threshold);
        //    thresholdEffect.Parameters["color1"].SetValue(color1.ToVector4());
        //    thresholdEffect.Parameters["color2"].SetValue(color2.ToVector4());

        //    foreach (EffectPass pass in thresholdEffect.CurrentTechnique.Passes)
        //    {
        //        spriteBatch.Begin(SpriteBlendMode.None, SpriteSortMode.Immediate, SaveStateMode.None);
        //        pass.Begin();

        //        spriteBatch.Draw(tex, new Rectangle(0, 0, tex.Width, tex.Height), Color.White);
        //        pass.End();
        //        spriteBatch.End();
        //    }

        //    thresholdEffect.End();

        //    graphics.SetRenderTarget(0, null);
        //    result = target.GetTexture();
        //    target.Dispose();
        //    return result;

        //}
    }
}
